package plus.exp;

import plus.B;
import plus.run.Emit;
import plus.run.Label;

public class E_Conditional extends Exp {
	final Exp condition, ifTrue, ifFalse;
	public E_Conditional(Exp condition, Exp ifTrue, Exp ifFalse) {
		this.condition = condition;
		this.ifTrue = ifTrue;
		this.ifFalse = ifFalse;
	}
	@Override
	public void threadScope() {
		condition.threadScope();
		ifTrue.threadScope();
		ifFalse.threadScope();
		condition.unify_with(B._bool);
		type = ifTrue.unify_with(ifFalse);
	}
	@Override String impliedName() { return null; }
	@Override String aThis() { return "a condition expression"; }
	@Override
	public void compilePush() {
		Label onFalse = new Label();
		Label after = new Label();
		condition.compileJcc(onFalse, false);
		Emit.pop();
		ifTrue.compilePush();
		after.JMP();
		onFalse.post();
		Emit.pop();
		ifFalse.compilePush();
		after.post();
	}
	@Override
	public void compileJcc(Label where, boolean when) {
		Label onFalse = new Label();
		Label after = new Label();
		condition.compileJcc(onFalse, false);
		Emit.pop();
		ifTrue.compileJcc(where, when);
		after.JMP();
		onFalse.post();
		Emit.pop();
		ifFalse.compileJcc(where, when);
		after.post();
	}
}
